﻿using System;
using System.Drawing;
using System.Windows.Forms;
using HighDiveEngine.Aggregates;
using HighDiveEngine.Model;
using HighDiveEngine.Resources;
using System.Text.RegularExpressions;

namespace HighDiveAdmin.GUI.Components
{
    public partial class EditContestScreen : UserControl
    {
        private bool _createContest = false;
        private EditContestList _contestListPanel;     //only shown when window is large enough
        //public event DelegateVoidStringInt EventLoadJudgeToTextBox;
        public event DelegateVoidStringInt EventUpdateActiveJudge;
        public event DelegateJudgeInt EventAddEditJudge;
        public event DelegateVoidString EventLoadJudge;
        public event DelegateVoidString EventLoadDiver;
        public event DelegateVoidString EventEditDiver;
        public event DelegateDoubleStringInt EventCalculateDiveDifficulty;
        public event DelegateVoidJudgeEventArgs EventSaveJudge;
        public event DelegateVoidInt EventSetNumberOfJudges;
        public event DelegateVoidInt EventEditContestAddDiver;
        public event DelegateDiveListDiver EventEditContestAddDiveList;
        public event DelegateVoidPersonEventArgsDiveEventArgsArray EventSaveDiver;
        public event DelegateVoidContest EventLoadContestToEdit;
        public event DelegateVoidBool EventDiscard;
        public event DelegateVoidContestEventArgs EventSave;
        public event DelegateVoidContestEventArgs EventSaveAndStart;
        public event DelegateVoidContestEventArgs EventUpdateContestInformation;
        public event MethodInvoker EventGoBack;
        public event DelegateDiverEventArgs EventRemoveDiver;
        public event DelegateDiveEventArgs EventRemoveDive;

        #region TabAreas

        #region TabProcessing
        /// <summary>
        /// Function to be triggered when the user presses Ctrl+Tab, handles changing which tab area is active
        /// </summary>
        public void ProcessCtrlTab()
        {
            switch (TabArea)
            {
                case ActiveTabArea.Area1:
                    if (panelMain.Visible)
                    TabArea = ActiveTabArea.Area2;
                    break;
                case ActiveTabArea.Area2:
                    TabArea = ActiveTabArea.Area3;
                    break;
                case ActiveTabArea.Area3:
                    TabArea = ActiveTabArea.Area4;
                    break;
                case ActiveTabArea.Area4:
                    TabArea = ActiveTabArea.Area5;
                    break;
                case ActiveTabArea.Area5:
                    if (_contestListPanel.Visible)
                        TabArea = ActiveTabArea.Area1;
                    else
                        TabArea = ActiveTabArea.Area2;
                    break;
            }
        }

        /// <summary>
        /// Function to be triggered when the user presses Ctrl+Shift+Tab, handles changing which tab area is active
        /// </summary>
        public void ProcessShiftCtrlTab()
        {
            switch (TabArea)
            {
                case ActiveTabArea.Area1:
                    if (panelMain.Visible)
                        TabArea = ActiveTabArea.Area5;
                    break;
                case ActiveTabArea.Area2:
                    if(_contestListPanel.Visible)
                        TabArea = ActiveTabArea.Area1;
                    else
                        TabArea = ActiveTabArea.Area5;
                    break;
                case ActiveTabArea.Area3:
                    TabArea = ActiveTabArea.Area2;
                    break;
                case ActiveTabArea.Area4:
                    TabArea = ActiveTabArea.Area3;
                    break;
                case ActiveTabArea.Area5:
                    TabArea = ActiveTabArea.Area4;
                    break;
            }
        }
        #endregion

        #region Property
        private enum ActiveTabArea
        {
            Area1,
            Area2,
            Area3,
            Area4,
            Area5
        }

        private ActiveTabArea _activeTabArea;

        private ActiveTabArea TabArea
        {
            get { return _activeTabArea; }
            set
            {
                _activeTabArea = value;
                switch (value)
                {
                    case ActiveTabArea.Area1:
                        _setArea1Active();
                        break;
                    case ActiveTabArea.Area2:
                        _setArea2Active();
                        break;
                    case ActiveTabArea.Area3:
                        _setArea3Active();
                        break;
                    case ActiveTabArea.Area4:
                        _setArea4Active();
                        break;
                    case ActiveTabArea.Area5:
                        _setArea5Active();
                        break;
                }
            }
        }
        #endregion

        #region SetActiveArea

        private void _setArea1Active()
        {
            _setArea1(true);
            _setArea2(false);
            _setArea3(false);
            _setArea4(false);
            _setArea5(false);
        }
        private void _setArea2Active()
        {
            _setArea1(false);
            _setArea2(true);
            _setArea3(false);
            _setArea4(false);
            _setArea5(false);
        }
        private void _setArea3Active()
        {
            _setArea1(false);
            _setArea2(false);
            _setArea3(true);
            _setArea4(false);
            _setArea5(false);
        }
        private void _setArea4Active()
        {
            _setArea1(false);
            _setArea2(false);
            _setArea3(false);
            _setArea4(true);
            _setArea5(false);
        }
        private void _setArea5Active()
        {
            _setArea1(false);
            _setArea2(false);
            _setArea3(false);
            _setArea4(false);
            _setArea5(true);
        }

        #endregion

        #region AreaSetFunctions
        private void _setArea1(bool enabled)
        {
            if (_contestListPanel.Visible)
                _contestListPanel.TabStop = enabled;
            if (buttonGoBack.Visible)
                buttonGoBack.TabStop = enabled;
        }

        private void _setArea2(bool enabled)
        {
            editContestDetailsPanel.TabStop = enabled;
        }

        private void _setArea3(bool enabled)
        {
            if (editContestJudgesPanel.Visible)
                editContestJudgesPanel.TabStop = enabled;
            else if (editContestNewJudgePanel.Visible)
                editContestNewJudgePanel.TabStop = enabled;
        }

        private void _setArea4(bool enabled)
        {
            if (editContestNewDiverPanel.Visible)
                editContestNewDiverPanel.TabStop = enabled;
            else if (editContestDiverList.Visible)
                editContestDiverList.TabStop = enabled;
        }

        private void _setArea5(bool enabled)
        {
            buttonDiscard.TabStop = enabled;
            buttonSaveAndStart.TabStop = enabled;
            buttonSave.TabStop = enabled;
            if (enabled)
                buttonSaveAndStart.Focus();
        }
        #endregion

        #region MouseAreaChange
        private void _runningContestSetArea1Active(object sender, EventArgs e)
        {
            if (TabArea != ActiveTabArea.Area1)
                TabArea = ActiveTabArea.Area1;
        }
        private void _runningContestSetArea2Active(object sender, EventArgs e)
        {
            if (TabArea != ActiveTabArea.Area2)
                TabArea = ActiveTabArea.Area2;
        }
        private void _runningContestSetArea3Active(object sender, EventArgs e)
        {
            if (TabArea != ActiveTabArea.Area3)
                TabArea = ActiveTabArea.Area3;
        }
        private void _runningContestSetArea4Active(object sender, EventArgs e)
        {
            if (TabArea != ActiveTabArea.Area4)
                TabArea = ActiveTabArea.Area4;
        }
        private void _runningContestSetArea5Active(object sender, EventArgs e)
        {
            if (TabArea != ActiveTabArea.Area5)
                TabArea = ActiveTabArea.Area5;
        }
        #endregion

        #endregion

        public EditContestScreen()
        {            
            _contestListPanel = new EditContestList
            {
                Location = new Point(0, 24),
                Height = this.Height - 24,
                Visible = true
            };
            
            Controls.Add(_contestListPanel);
            InitializeComponent();
            editContestJudgesPanel.Visible = true;
            editContestNewDiverPanel.EventDiscard += _newDiverPanelDiscard;
            editContestNewDiverPanel.EventLoadDiver += _newDiverPanelLoadDiver;
            editContestJudgesPanel.EventSetNumberOfJudges += _setNumberOfJudges;
            editContestNewJudgePanel.EventDiscard += Discard;
            editContestJudgesPanel.EventNewJudge += _showNewJudgePanel;
            editContestNewJudgePanel.EventSaveJudge += _saveJudge;
            editContestDiverList.EventAddDiver += _addDiver;
            editContestDiverList.EventRemoveDive += _removeDive;
            editContestDiverList.EventRemoveDiver += _removeDiver;
            _contestListPanel.EventLoadContestToEdit += _loadContestToEdit;
            TabArea = ActiveTabArea.Area1;
        }

        private void _removeDive(DiveEventArgs diveEventArgs)
        {
            if (EventRemoveDive != null)
                EventRemoveDive(diveEventArgs);
        }

        private void _removeDiver(DiverEventArgs diverEventArgs)
        {
            if (EventRemoveDiver != null)
                EventRemoveDiver(diverEventArgs);
        }

        private void _loadContestToEdit(Contest contest)
        {
            if (EventLoadContestToEdit != null)
            {
                if (Width > 1165)
                    _showEditContestListAndEditContest();
                else
                    _showEditContestOnly();

                EventLoadContestToEdit(contest);
            }
        }
        

        private void _addDiver(int startNumber)
        {
            if (EventEditContestAddDiver != null)
                EventEditContestAddDiver(startNumber);
        }


        private void _saveJudge(JudgeEventArgs judgeArgs)
        {
            if (EventSaveJudge != null)
                EventSaveJudge(judgeArgs);
        }

        private void _showNewJudgePanel()
        {
            editContestNewJudgePanel.Visible = true;
            TabArea = ActiveTabArea.Area3;
        }

        private void Discard()
        {
            editContestJudgesPanel.Visible = true;
            editContestJudgesPanel.BringToFront();
        }

        private void _setNumberOfJudges(int number)
        {
            if (EventSetNumberOfJudges != null)
                EventSetNumberOfJudges(number);
        }

        private void _newDiverPanelLoadDiver(string idNumber)
        {
            if (EventLoadDiver != null) 
                EventLoadDiver(idNumber);
        }

        private void _newDiverPanelDiscard()
        {
            editContestNewDiverPanel.Visible = false;
            editContestDiverList.Visible = true;
        }

        public void ShowNewJudgePanel(Judge judge)
        {
            editContestNewJudgePanel.Show(judge);
            //editContestJudgesPanel.FillJudgeBox(judge, judge.JudgeNumber);
            TabArea = ActiveTabArea.Area3;
        }

        public void ShowJudgesPanel(JudgeList judgeList)
        {
            editContestJudgesPanel.Show(judgeList);
            TabArea = ActiveTabArea.Area3;
        }

        private void EditContestScreen_Resize(object sender, EventArgs e)
        {
            _contestListPanel.Height = this.Height - 24;
            if (Width > 1165)
            {
                if (_createContest || editContestDetailsPanel.ContestLoaded())
                    _showEditContestListAndEditContest();
                else
                    _showEditContestListOnly();
            }
                
            else
            {
                if (_createContest || editContestDetailsPanel.ContestLoaded())
                    _showEditContestOnly();
                else
                    _showEditContestListOnly();
            } 
        }

        private void _showEditContestListOnly()
        {
            editContestDetailsPanel.Visible = false;
            editContestDiverList.Visible = false;
            editContestJudgesPanel.Visible = false;
            editContestNewDiverPanel.Visible = false;
            editContestNewJudgePanel.Visible = false;
            buttonGoBack.Enabled = true;
            _contestListPanel.Visible = true;
            //_contestListPanel.Location = new Point(0,24);
            panelMain.Location = new Point(0, 24);
            panelMain.Anchor = ((AnchorStyles.Left | AnchorStyles.Top) | AnchorStyles.Bottom);
            if (TabArea != ActiveTabArea.Area1)
                TabArea = ActiveTabArea.Area1;
        }
        private void _showEditContestListAndEditContest()
        {
            editContestDetailsPanel.Visible = true;
            editContestDiverList.Visible = true;
            editContestJudgesPanel.Visible = true;
            editContestNewDiverPanel.Visible = false;
            editContestNewJudgePanel.Visible = false;
            buttonGoBack.Enabled = false;
            _contestListPanel.Visible = true;
            panelMain.Location = new Point(381, 24);
            panelMain.Anchor = ((AnchorStyles.Left | AnchorStyles.Top) | AnchorStyles.Bottom);
           
        }

        private void _showEditContestOnly()
        {
            editContestDetailsPanel.Visible = true;
            editContestDiverList.Visible = true;
            editContestJudgesPanel.Visible = true;
            editContestNewDiverPanel.Visible = false;
            editContestNewJudgePanel.Visible = false;
            buttonGoBack.Enabled = false;
            _contestListPanel.Visible = false;
            panelMain.Location = new Point(0, 24);
            panelMain.Anchor = ((AnchorStyles.Left | AnchorStyles.Top) | AnchorStyles.Bottom);
            if (TabArea == ActiveTabArea.Area1)
                TabArea = ActiveTabArea.Area2;
        }

        private void EditContest_UpdateJudge(string id, int number)
        {
            if (EventUpdateActiveJudge != null)
                EventUpdateActiveJudge(id, number);
        }

        internal void FillEditorWithContest(Contest contest, PersonList personList)
        {
            editContestDetailsPanel.FillDetails(contest);
            editContestJudgesPanel.FillJudges(contest);
            UpdatePersonLists(personList);
            
            editContestNewJudgePanel.Visible = false;
            editContestJudgesPanel.Visible = true;
            editContestNewDiverPanel.Visible = false;

            editContestJudgesPanel.Show(contest.JudgeList);
            editContestDiverList.Show(contest.DiveQueue);
            TabArea = ActiveTabArea.Area2;
        }


        public void UpdateContestList(ContestList contestList)
        {
            _contestListPanel.Update(contestList);
        }

        public void ShowDiverTreeView(DiveList diveList)
        {
            editContestDiverList.Show(diveList);
            TabArea = ActiveTabArea.Area4;
        }

        internal void FillContestHistory(ContestList contestHistoryList)
        {
            if (_contestListPanel != null)
                _contestListPanel.SetDataSource(contestHistoryList);
        }

        internal void FillExistingJudgeFromIdNumber(Person person)
        {
            editContestNewJudgePanel.FillExistingJudgeFromIdString(person);
        }

        public void FillExistingDiverFromIdNumber(Person person)
        {
            editContestNewDiverPanel.FillExistingDiverFromIdNumber(person);
        }

        private double editContestNewDiverPanel_EventCalculateDifficulty(string str1, int i)
        {
            if (EventCalculateDiveDifficulty != null) return 
                EventCalculateDiveDifficulty(str1, i);
            return 0;
        }

        private void editContestNewDiverPanel_EventSaveDiver(DiverEventArgs diverArgs, DiveEventArgs[] diveArgs)
        {
            if (EventSaveDiver != null)
                EventSaveDiver(diverArgs, diveArgs);
        }

        public void FillNewDiverPanel(Diver diver, DiveList diveList)
        {
            editContestNewDiverPanel.Show(diver, diveList);
            TabArea = ActiveTabArea.Area4;
        }

        private void editContestDiverList_EventLoadDiver(string idNumber)
        {
            if (EventEditDiver != null) 
                EventEditDiver(idNumber);
        }

        private void buttonDiscard_Click(object sender, EventArgs e)
        {
            if (EventDiscard != null)
            {
                EventDiscard(_createContest);
                editContestDetailsPanel.Clear();
                EditContestScreen_Resize(null,null);
            }
        }

        internal void SetCreateContest(bool p)
        {
            _createContest = p;
        }

        private void buttonSave_Click(object sender, EventArgs e)
        {
            if (!(new Regex(@"^[a-zA-Z0-9 åäöüÅÄÖ]+$").IsMatch(editContestDetailsPanel.GetName())))
                MessageBox.Show("Enter Contest Name!");
            else
            {
                if (EventSave != null)
                {
                    EventSave(editContestDetailsPanel.GetContestArgs());
                    if (_createContest)
                        _createContest = false;
                }
                editContestDetailsPanel.Clear();
                EditContestScreen_Resize(null, null);
            }
        }

        private void editContestNewJudgePanel_EventLoadJudge(string idNumber)
        {
            if (EventLoadJudge != null)
                EventLoadJudge(idNumber);
        }

        internal void FillNewJudgePanel(Judge judge)
        {
            editContestNewJudgePanel.Show(judge);
        }

        public void UpdatePersonLists(PersonList personList)
        {
            editContestNewJudgePanel.FillJudgeInfo(personList);
            editContestNewDiverPanel.FillDiverInfo(personList);
        }

        private void editContestJudgesPanel_EventUpdateJudge(int number)
        {
            Judge judge = null;
            if (EventAddEditJudge != null)
                judge = EventAddEditJudge(number);
            editContestNewJudgePanel.Show(judge);
        }

        private void EditContestScreen_VisibleChanged(object sender, EventArgs e)
        {
            if(Visible)
                EditContestScreen_Resize(null, null);
        }

        private void buttonGoBack_Click(object sender, EventArgs e)
        {
            if (EventGoBack != null)
                EventGoBack();
        }

        private void buttonSaveAndStart_Click(object sender, EventArgs e)
        {
            if (EventSaveAndStart != null)
                EventSaveAndStart(editContestDetailsPanel.GetContestArgs());
        }
    }
}
